from typing import List

from sqlalchemy import and_, select, update

from forward.api.admin.schemas.lucky.activity import ActivityListOutSchema
from forward.dependencies.database import db
from forward.model.orm.base import BaseORM
from forward.model.schemas.lucky.activity import (
    ActivityCodeNoSchema,
    ActivityOutSchema,
    ActivityPrizeOutSchema,
)
from forward.model.tables.activity import (
    ActivityCodeNoModel,
    ActivityModel,
    ActivityPrizeModel,
)
from forward.model.tables.merchant import MerchantModel
from forward.utils.page_utils import PageSchema, PageUtils


class ActivityORM(BaseORM[ActivityOutSchema]):
    MODEL = ActivityModel
    OUT_SCHEMA = ActivityOutSchema

    async def lists(
        self,
        page_num: int,
        page_size: int,
        where: list = [],
        order_by: list = [ActivityModel.id.desc()],
    ) -> PageSchema[ActivityListOutSchema]:
        statement = (
            select(ActivityModel, MerchantModel.name.label("merchant_name"))
            .where(*where)
            .outerjoin(MerchantModel, MerchantModel.id == ActivityModel.merchant_id)
            .order_by(and_(*order_by))
        )
        pagination = await PageUtils.paginate(
            db=db,
            query=statement,
            page_num=page_num,
            page_size=page_size,
            schema=ActivityListOutSchema,
        )
        return pagination

    async def get_prizes_by_activity_id(
        self, activity_id: int
    ) -> List[ActivityPrizeOutSchema] | None:
        statement = select(ActivityPrizeModel).where(
            ActivityPrizeModel.activity_id == activity_id
        )
        records = await db.fetch_all(statement)
        if not records:
            return []
        return [
            ActivityPrizeOutSchema.model_validate(record, from_attributes=True)
            for record in records
        ]

    async def get_ids_by_merchant_id(self, merchant_id: int) -> List[int]:
        statement = select(ActivityModel).where(
            ActivityModel.merchant_id == merchant_id
        )
        recodes = await db.fetch_all(statement)
        if not recodes:
            return []
        return [
            ActivityOutSchema.model_validate(recode, from_attributes=True).id
            for recode in recodes
        ]
